package com.lu.model.entity;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.*;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门表
 * </p>
 *
 * @author wangqieyu
 * @since 2022-07-26
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SysDept extends Model<SysDept> {

    private static final long serialVersionUID = 1L;

    /**
     * 部门id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 父部门id
     */
    private Long pid;

    /**
     * 部门名称
     */
    private String name;

    /**
     * 显示顺序
     */
    private Integer sort;

    /**
     * 负责人
     */
    private String leader;

    /**
     * 联系电话
     */
    private String phone;

    /**
     * 部门状态（0停用 1正常）
     * @see com.lu.model.enums.YesOrNoEnum
     */
    private Integer status;

    /**
     * 创建者
     */
    private Long createUserId;

    /**
     * 更新者
     */
    private Long updateUserId;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;


    @Override
    protected Serializable pkVal() {
        return this.id;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class TreeNodes {
        private Long id;
        private Long pid;
        private String name;
        /**
         * @see com.lu.model.enums.YesOrNoEnum
         */
        private Integer status;
        private Integer sort;
        private List<TreeNodes> childs;
    }

    public static List<TreeNodes> treeNodes(List<SysDept> deptList, Long pid){
        List<TreeNodes> treeNodes = new ArrayList<>();
        if(ObjectUtil.isEmpty(deptList)){
            return treeNodes;
        }
        if(pid == null){
            pid = 0L;
        }
        //pid 下的孩子
        Map<Long, List<SysDept>> deptMap = deptList.stream().filter(o -> o.getPid() != 0).collect(Collectors.groupingBy(SysDept::getPid));
        Long finalPid = pid;
        List<SysDept> depts = deptList.stream().filter(o -> {
            if(finalPid == 0L){
                return o.getPid() == 0L;
            }else {
                return o.getId().longValue() == finalPid;
            }
        }).collect(Collectors.toList());
        for (SysDept dept : depts) {  //迭代父节点
            //父节点找孩子
            List<TreeNodes> childs = treeChildNodes(null, deptMap, dept.getId());
            if(ObjectUtil.isNotEmpty(childs)){
                childs = childs.stream().sorted(Comparator.comparing(o -> o.getSort())).collect(Collectors.toList());
            }
            treeNodes.add(TreeNodes.builder().id(dept.getId()).pid(dept.getPid())
                .name(dept.getName()).status(dept.getStatus()).sort(dept.getSort()).childs(childs).build());
        }
        return treeNodes.stream().sorted(Comparator.comparing(o -> o.getSort())).collect(Collectors.toList());
    }

    public static List<TreeNodes> treeChildNodes(List<TreeNodes> treeNodes, Map<Long, List<SysDept>> deptMap, Long pid){
        List<SysDept> depts = deptMap.get(pid);
        if(ObjectUtil.isEmpty(depts)){
            return treeNodes;
        }
        if(treeNodes == null){
            treeNodes = new ArrayList<>();
        }
        for (SysDept dept : depts) {
            //父节点找孩子
            List<TreeNodes> childs = treeChildNodes(null, deptMap, dept.getId());
            if(ObjectUtil.isNotEmpty(childs)){
                childs = childs.stream().sorted(Comparator.comparing(o -> o.getSort())).collect(Collectors.toList());
            }
            treeNodes.add(TreeNodes.builder().id(dept.getId()).pid(dept.getPid())
                .name(dept.getName()).status(dept.getStatus()).sort(dept.getSort()).childs(childs).build());
        }
        return treeNodes;
    }

    //测试
    public static void main(String[] args) {
        List<SysDept> depts = new ArrayList<>();
        depts.add(SysDept.builder().id(1L).pid(0L).name("A公司").sort(0).build());
        depts.add(SysDept.builder().id(2L).pid(0L).name("B公司").sort(0).build());
        depts.add(SysDept.builder().id(3L).pid(1L).name("技术部").sort(0).build());
        depts.add(SysDept.builder().id(4L).pid(1L).name("运营部").sort(0).build());
        depts.add(SysDept.builder().id(5L).pid(3L).name("开发部").sort(0).build());
        depts.add(SysDept.builder().id(6L).pid(3L).name("产品部").sort(0).build());
        depts.add(SysDept.builder().id(7L).pid(3L).name("测试部").sort(0).build());
        depts.add(SysDept.builder().id(8L).pid(5L).name("后端开发").sort(0).build());
        depts.add(SysDept.builder().id(9L).pid(5L).name("前端开发").sort(-1).build());
        depts.add(SysDept.builder().id(10L).pid(6L).name("需求分析部").sort(0).build());
        depts.add(SysDept.builder().id(11L).pid(6L).name("UI设计部").sort(0).build());
        List<TreeNodes> treeNodes = treeNodes(depts, 3L);
        System.out.println(JSON.toJSONString(treeNodes));
    }


}
